use config_plus::Configuration;
use serde::Deserialize;

/// 日志配置
#[derive(Deserialize, Configuration)]
#[config(
    file(path = "tracing-log.yml"),
    file(path = "tracing-log.yaml"),
    file(path = "tracing-log.toml"),
    env(name = "TRACING_LOG_FILE"),
    environment = false
)]
#[serde(rename_all = "kebab-case")]
pub(crate) struct TracingLog {
    /// 最小日志级别
    pub(crate) min_level: Option<String>,
    /// 控制台
    #[serde(default)]
    pub(crate) console: Console,
    /// 文件
    #[serde(default)]
    pub(crate) file: Vec<FileAppender>,
}

/// 控制台输出
///
/// 时间格式参考：[chrono::format::strftime]
///
/// [chrono::format::strftime]: https://docs.rs/chrono/0.4.9/chrono/format/strftime/index.html
#[derive(Deserialize)]
#[serde(rename_all = "kebab-case")]
pub(crate) struct Console {
    /// 日志级别, 必填
    pub(crate) level: String,
    /// 是否打印线程名
    #[serde(default = "thread_default")]
    pub(crate) thread: bool,
    /// 时间格式化
    #[serde(default = "format_default")]
    pub(crate) format: String,
    /// 是否打印行号
    #[serde(default)]
    pub(crate) line_number: bool,
}

impl Default for Console {
    fn default() -> Self {
        Console {
            level: "info".to_string(),
            thread: true,
            format: "%Y-%m-%d %H:%M:%S".to_string(),
            line_number: false,
        }
    }
}

/// 文件追加
///
/// 时间格式参考：[chrono::format::strftime]
///
/// [chrono::format::strftime]: https://docs.rs/chrono/0.4.9/chrono/format/strftime/index.html
#[derive(Deserialize)]
#[serde(rename_all = "kebab-case")]
pub(crate) struct FileAppender {
    /// 日志级别, 必填，可选值："error"、"warn"、"info"、"debug"、"trace"
    pub(crate) level: String,
    /// 是否打印线程名, 默认值为: true
    #[serde(default = "thread_default")]
    pub(crate) thread: bool,
    /// 时间格式化, 默认值为: "%Y-%m-%d %H:%M:%S"
    #[serde(default = "format_default")]
    pub(crate) format: String,
    /// 是否打印行号, 默认值为: false
    #[serde(default)]
    pub(crate) line_number: bool,
    /// 保留的最大日志个数, 默认值为: 30
    #[serde(default = "max_files_default")]
    pub(crate) max_files: usize,
    /// 日志文件滚动的固定时间段，可选值: "minutely"、"hourly"、"daily"、"never", 默认值为: "daily"
    #[serde(default = "rotation_default")]
    pub(crate) rotation: String,
    /// 生成的文件名前缀, 必填
    pub(crate) prefix: String,
    /// 生成的文件名后缀, 默认值为: "log"
    #[serde(default = "suffix_default")]
    pub(crate) suffix: String,
    /// 生成的文件的目录
    #[serde(default = "directory_default")]
    pub(crate) directory: String,
    /// 只记录`target`指定的值的日志
    #[serde(default = "target_default")]
    pub(crate) target: String,
}

fn thread_default() -> bool {
    true
}

fn format_default() -> String {
    String::from("%Y-%m-%d %H:%M:%S")
}

fn max_files_default() -> usize {
    30
}

fn rotation_default() -> String {
    String::from("daily")
}

fn suffix_default() -> String {
    String::from("log")
}

fn directory_default() -> String {
    String::from("./logs")
}
fn target_default() -> String {
    String::from("")
}
